﻿using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.Linq;
using System.Xml;
using Autodesk.Revit.DB;
using Autodesk.Revit.UI;
using YArchitech.LIB;
using YArchitech.Revit;
using YJKArchUtils.Utils;
using YJKRevitBase.Math;
using YJKRevitBase.XmlUtility;
using YJKRevitKernel.ElementSearchUtility.LinkDocumentSuite;
using YJKRevitKernel.RevitTopologySuite;
using YJKRevitDimensionText.DimCreator;
using YJKRevitDimensionText.OneKeyPlanDim.Utility;
using YJKRevitDimensionText.VerticalAutoDim.Comparer;
using YJKRevitDimensionText.VerticalAutoDim.GeoModel;
using YJKRevitDimensionText.VerticalAutoDim.Group;
using YJKRevitDimensionText.VerticalAutoDim.OutWallSearch;
using YJKRevitDimensionText.VerticalAutoDim.ProgressBar;

namespace YJKRevitDimensionText.VerticalAutoDim
{
	internal class VerticalAutoDimManager
	{
		private List<OutWallData> ArrayOutWallByViewDirection { get; set; }

		private List<OutWallData> ArrayOutWallByViewDirectionAtView { get; set; }

		public IList<IPlanarGeo> ArrayOutWallGeoByViewDirectionAtViewVisable
		{
			get
			{
				return this.OutWallSortAlgorithm.ArrayWallGeoVisable;
			}
		}

		public IList<IPlanarGeo> ArrayWindDoorInOutWallDataVisable
		{
			get
			{
				return this.OutWallSortAlgorithm.ArrayWindDoorGeoInOutWallVisable;
			}
		}

		public IList<IPlanarGeo> ArrayLevelGeo { get; private set; }

		public List<IPlanarGeo> ArrayTopMostGeo
		{
			get
			{
				return this.OutWallSortAlgorithm.ArrayTopMostGeo;
			}
		}

		public IList<IPlanarGeo> ArrayPlanarGeo
		{
			get
			{
				List<IPlanarGeo> list = new List<IPlanarGeo>();
				list.AddRange(this.ArrayOutWallGeoByViewDirectionAtViewVisable);
				list.AddRange(this.ArrayWindDoorInOutWallDataVisable);
				list.AddRange(this.ArrayTopMostGeo);
				return list;
			}
		}

		public XYZ MaxRegionPoint { get; private set; }

		public XYZ MinRegionPoint { get; private set; }

		public VerticalAutoDimManager(UIApplication uiApp, Autodesk.Revit.DB.Document doc, IList<ViewPlan> arrayViewPlan, IDualStatusProgressBarProcess progressBarForm)
		{
			this.DualStatusProgressBarProcess = progressBarForm;
			this.UIApplication = uiApp;
			this.Doc = doc;
			this.ArrayViewPlan = arrayViewPlan;
			this.Plane = Utility.CreatePlaneByView(this.Doc.ActiveView);
			this.TransformWcs2Plane = Utility.CreateTransformByPlane(this.Plane);
		}

		public bool Init()
		{
			int i = 0;
			this.DualStatusProgressBarProcess.UpdatePrimaryStatus(0);
			this.DualStatusProgressBarProcess.SetSubStatusMaxVal(this.ArrayViewPlan.Count);
			this.ArrayLevelGeo = new List<IPlanarGeo>();
			EnumerableExternsion.ForEach<ViewPlan>(this.ArrayViewPlan, delegate(ViewPlan v)
			{
				this.ArrayLevelGeo.Add(new LevelGeo(v.GenLevel, this.Plane, this.TransformWcs2Plane));
				IDualStatusProgressBarProcess dualStatusProgressBarProcess = this.DualStatusProgressBarProcess;
				int i2 = i;
				i++;
				dualStatusProgressBarProcess.UpdateSubStatus(i2);
			});
			this.OutWallSearch();
			this.CreatePlanarGeo();
			this.ClipPlanarGeoCropBox();
			this.OutWallSortAlgorithm.GetTopGeo(this.MaxRegionPoint, this.MinRegionPoint);
			return true;
		}

		public bool DoGeoGroup()
		{
			try
			{
				GeoGroupData geoGroupData = new GeoGroupData(this.ArrayLevelGeo, this.ArrayWindDoorInOutWallDataVisable, this.ArrayTopMostGeo);
				this.GeoGroupManager = new GeoGroupManager(geoGroupData, this.MinRegionPoint, this.MaxRegionPoint, this.TransformWcs2Plane, this.Doc);
				return this.GeoGroupManager.Calc();
			}
			catch
			{
			}
			return false;
		}

		public IList<Element> DoDim()
		{
			List<Element> result = new List<Element>();
			TransactionGroup transactionGroup = new TransactionGroup(this.Doc, "DoDim");
			try
			{
				transactionGroup.Start();
				this.DeleteExistedDimension();
				int num = 0;
				this.DualStatusProgressBarProcess.UpdatePrimaryStatus(4);
				this.DualStatusProgressBarProcess.SetSubStatusMaxVal(5);
				DimensionType dimensionType = this.GetDimensionType();
				List<Dimension> lstThreeDimLines = this.DoThreeDim(dimensionType);
				this.DualStatusProgressBarProcess.UpdateSubStatus(num++);
				this.DoDimWinDoor(dimensionType, lstThreeDimLines);
				this.DualStatusProgressBarProcess.UpdateSubStatus(num++);
				this.DoElevDim();
				this.DualStatusProgressBarProcess.UpdateSubStatus(num++);
				this.DoDimRailing(dimensionType);
				this.DualStatusProgressBarProcess.UpdateSubStatus(num++);
				this.ModifyLevel();
				this.DualStatusProgressBarProcess.UpdateSubStatus(num++);
				transactionGroup.Assimilate();
			}
			catch (ProgressUserTerminalException ex)
			{
				transactionGroup.RollBack();
				throw ex;
			}
			catch (Exception)
			{
				transactionGroup.RollBack();
			}
			return result;
		}

		private IList<Element> GetWallElementByView()
		{
			List<BaseLinkDocumentResultBean> list = new FilteredElementCollectorLinkDocument(this.Doc).OfCategory(BuiltInCategory.OST_Walls).WhereElementIsNotElementType().ToList<BaseLinkDocumentResultBean>();
			List<Element> list2 = new List<Element>();
			foreach (BaseLinkDocumentResultBean baseLinkDocumentResultBean in list)
			{
				list2.Add(baseLinkDocumentResultBean.UseElement);
			}
			return list2;
		}

		private bool CreatePlanarGeo()
		{
			this.OutWallSortAlgorithm = new OutWallSortAlgorithm(this.Doc, this.ArrayOutWallByViewDirectionAtView, this.Plane, this.TransformWcs2Plane, this.DualStatusProgressBarProcess);
			this.OutWallSortAlgorithm.SortOutWallByViewDepth();
			this.OutWallSortAlgorithm.SortOutWallWindDoorByViewDepth();
			this.OutWallSortAlgorithm.CreatePlanarGeo();
			return true;
		}

		private bool ClipPlanarGeoCropBox()
		{
			try
			{
				Outline planarGeoBoxRegion = Utility.GetPlanarGeoBoxRegion(this.ArrayPlanarGeo);
				if (planarGeoBoxRegion == null)
				{
					return false;
				}
				BoundingBoxXYZ viewCropRegion = Utility.GetViewCropRegion(this.Doc);
				if (viewCropRegion != null)
				{
					Transform transformEcs2Wcs = this.Doc.ActiveView.CropBox.Transform;
					Transform inverse = transformEcs2Wcs.Inverse;
					XYZ ptMinWcs = inverse.OfPoint(viewCropRegion.Min);
					XYZ ptMaxWcs = inverse.OfPoint(viewCropRegion.Max);
					CurveLoop curveLoop = CurveLoop.Create(this.CreateCurveBoxInViewPlane(ptMinWcs, ptMaxWcs));
					XYZ ptMinWcs2 = inverse.OfPoint(planarGeoBoxRegion.MinimumPoint);
					XYZ ptMaxWcs2 = inverse.OfPoint(planarGeoBoxRegion.MaximumPoint);
					CurveLoop curveLoop2 = CurveLoop.Create(this.CreateCurveBoxInViewPlane(ptMinWcs2, ptMaxWcs2));
					RevitPolygonDataBean revitPolygonDataBean = new RevitPolygonDataBean(curveLoop, null, 3);
					RevitPolygonDataBean revitPolygonDataBean2 = new RevitPolygonDataBean(curveLoop2, null, 3);
					RevitPolygonBooleanOperater revitPolygonBooleanOperater = new RevitPolygonBooleanOperater();
					List<RevitOperationDataBean> list = null;
                    if (revitPolygonBooleanOperater.TryGetBooleanResult(revitPolygonDataBean, revitPolygonDataBean2, (YJKRevitBase.TopologySuite.BooleanOperatorKindEnum)0, out list))
					{
						List<XYZ> lstPtWcs = new List<XYZ>();
                        //Action<Curve> <>9__1;
						list.ForEach(delegate(RevitOperationDataBean result)
						{
							List<Curve> lstRevitCurve = result.LstRevitCurve;
							Action<Curve> action;
                            //if ((action = <>9__1) == null)
                            //{
                            //    action = (<>9__1 = delegate(Curve cv)
                            //    {
                            //        XYZ endPoint = cv.GetEndPoint(0);
                            //        XYZ endPoint2 = cv.GetEndPoint(1);
                            //        lstPtWcs.Add(transformEcs2Wcs.OfPoint(endPoint));
                            //        lstPtWcs.Add(transformEcs2Wcs.OfPoint(endPoint2));
                            //    });
                            //}
                            //lstRevitCurve.ForEach(action);
						}
                        
                        );
						if (lstPtWcs.Count > 0)
						{
							Outline outline = new Outline(lstPtWcs.First<XYZ>(), lstPtWcs.First<XYZ>());
							lstPtWcs.ForEach(delegate(XYZ p)
							{
								outline.AddPoint(p);
							});
							this.MinRegionPoint = outline.MinimumPoint;
							this.MaxRegionPoint = outline.MaximumPoint;
							return true;
						}
					}
				}
				this.MinRegionPoint = planarGeoBoxRegion.MinimumPoint;
				this.MaxRegionPoint = planarGeoBoxRegion.MaximumPoint;
				return true;
			}
			catch
			{
			}
			return false;
		}

		private IList<Curve> CreateCurveBoxInViewPlane(XYZ ptMinWcs, XYZ ptMaxWcs)
		{
			if (ptMinWcs == null || ptMaxWcs == null)
			{
				return null;
			}
			XYZ rightDirection = this.Doc.ActiveView.RightDirection;
			XYZ upDirection = this.Doc.ActiveView.UpDirection;
			XYZ xyzpoint = Line.CreateUnbound(ptMinWcs, rightDirection).Project(ptMaxWcs).XYZPoint;
			XYZ xyzpoint2 = Line.CreateUnbound(ptMaxWcs, rightDirection).Project(ptMinWcs).XYZPoint;
			return new List<Curve>(4)
			{
				Line.CreateBound(ptMinWcs, xyzpoint),
				Line.CreateBound(xyzpoint, ptMaxWcs),
				Line.CreateBound(ptMaxWcs, xyzpoint2),
				Line.CreateBound(xyzpoint2, ptMinWcs)
			};
		}

		private bool OutWallSearch()
		{
			IOutWallCreator outWallCreator = new OutRoomOutWallCreator(this.Doc, this.ArrayViewPlan, this.DualStatusProgressBarProcess);
			using (OutWallSearcherManager outWallSearcherManager = new OutWallSearcherManager(this.UIApplication.Application, this.Doc, outWallCreator, this.DualStatusProgressBarProcess))
			{
				outWallSearcherManager.InitOutWallSearch();
				this.ArrayOutWallByViewDirection = outWallSearcherManager.ArrayOutWallByViewDirection.ToList<OutWallData>();
				this.GetOutWallByViewDirectionAtView();
			}
			return true;
		}

		private void GetOutWallByViewDirectionAtView()
		{
			this.ArrayOutWallByViewDirectionAtView = new List<OutWallData>();
			BoundingBoxXYZ viewCropRegion = Utility.GetViewCropRegion(this.Doc);
			if (viewCropRegion == null)
			{
				this.ArrayOutWallByViewDirection.ForEach(delegate(OutWallData c)
				{
					this.ArrayOutWallByViewDirectionAtView.Add(c);
				});
				return;
			}
			XYZ xyz = this.TransformWcs2Plane.OfPoint(viewCropRegion.Min);
			XYZ xyz2 = this.TransformWcs2Plane.OfPoint(viewCropRegion.Max);
			foreach (OutWallData outWallData in this.ArrayOutWallByViewDirection)
			{
				IPlanarGeo planarGeo = new BaseWallGeo(outWallData.Element, outWallData.Curve as Line, this.Plane, this.TransformWcs2Plane);
				planarGeo.Init();
				if (!MathUtility.LessThan(planarGeo.Max2DPointECS.X, xyz.X, 1E-06) && !MathUtility.GreaterThan(planarGeo.Min2DPointECS.X, xyz2.X, 1E-06))
				{
					this.ArrayOutWallByViewDirectionAtView.Add(outWallData);
				}
			}
		}

		private List<Dimension> DoThreeDim(DimensionType dimType)
		{
			List<Dimension> list = Utility.DoDim(this.Doc, this.GeoGroupManager.ArrayGeoGroupNode, dimType);
			if (list == null)
			{
				return null;
			}
			foreach (Dimension inputDim in list)
			{
				DimAvoidManager.ClearCache();
				DimAvoidManager.TryAutoAvoidForVertical(this.Doc, inputDim);
			}
			return list;
		}

		private void DoDimWinDoor(DimensionType dimType, List<Dimension> lstThreeDimLines)
		{
			if (this.GeoGroupManager.ArrayGeoVerticalDimResult.Count == 0 || lstThreeDimLines == null)
			{
				return;
			}
			List<Dimension> list = Utility.DoDimWinDoor(this.Doc, this.GeoGroupManager.ArrayGeoVerticalDimResult, dimType, this.TransformWcs2Plane);
			if (list == null)
			{
				return;
			}
			for (int i = 0; i < list.Count; i++)
			{
				Dimension inputDim = list[i];
				DimAvoidManager.ClearCache();
				List<DimensionSegmentInfor> lstSegmentInfor = new List<DimensionSegmentInfor>();
				lstSegmentInfor = DimAvoidManager.TryAutoAvoidForVertical(this.Doc, inputDim);
				DimAvoidManager.TryAutoAvoidElementForVertical(this.Doc, inputDim, this.GeoGroupManager.ArrayWindDoorGeo, this.GeoGroupManager.ArrayGeoVerticalDimResult[i].ArrayGeo, this.TransformWcs2Plane, lstSegmentInfor, lstThreeDimLines);
			}
		}

		private void DoElevDim()
		{
			List<IPlanarGeo> list = this.SpotGroupByLevel();
			if (list == null)
			{
				return;
			}
			SpotDimensionType spotDimType = this.GetSpotDimType();
			Utility.DoElevDim(this.Doc, list, spotDimType);
		}

		private void DoDimRailing(DimensionType dimType)
		{
			IPlanarGeo planarGeo = (from e in this.ArrayTopMostGeo
			where e.Weight == 6
			select e).FirstOrDefault<IPlanarGeo>();
			if (planarGeo == null)
			{
				return;
			}
			if (planarGeo is RailingGeo)
			{
				Dimension dimension = Utility.DoDimRailing(this.Doc, planarGeo, this.ArrayLevelGeo, dimType);
				if (dimension != null)
				{
					DimAvoidManager.ClearCache();
					DimAvoidManager.TryAutoAvoidForVertical(this.Doc, dimension);
				}
			}
		}

		private void ModifyLevel()
		{
			XYZ ptLeft = null;
			XYZ ptRight = null;
			this.GetLevelPosition(ref ptLeft, ref ptRight);
			Utility.ModifyLevel(this.Doc, this.ArrayLevelGeo, ptLeft, ptRight);
		}

		private DimensionType GetDimensionType()
		{
			Transaction transaction = new Transaction(this.Doc);
			DimensionType result;
			try
			{
				transaction.Start("get dimension type");
				DimensionType dimensionType = this.LoadDimensionType("线性尺寸标注样式", "HY-尺寸标注");
				transaction.Commit();
				result = dimensionType;
			}
			catch (Exception ex)
			{
				if (1 == (int)transaction.GetStatus())
				{
					transaction.RollBack();
				}
				throw ex;
			}
			return result;
		}

		private SpotDimensionType GetSpotDimType()
		{
			Transaction transaction = new Transaction(this.Doc);
			SpotDimensionType result;
			try
			{
				IList<Element> list = new FilteredElementCollector(this.Doc).OfClass(typeof(SpotDimensionType)).ToElements();
				if (list.Count == 0)
				{
					result = null;
				}
				else
				{
					SpotDimensionType spotDimensionType = null;
					foreach (Element element in list)
					{
						SpotDimensionType spotDimensionType2 = element as SpotDimensionType;
						if (spotDimensionType2.Name == "HY-高程点（项目）")
						{
							spotDimensionType = spotDimensionType2;
							break;
						}
					}
					if (spotDimensionType != null)
					{
						result = spotDimensionType;
					}
					else
					{
						transaction.Start("spot dimension type");
						spotDimensionType = (this.LoadDimensionType("高程点", "HY-高程点（项目）") as SpotDimensionType);
						transaction.Commit();
						result = spotDimensionType;
					}
				}
			}
			catch (Exception ex)
			{
				if (1 == (int)transaction.GetStatus())
				{
					transaction.RollBack();
				}
				throw ex;
			}
			return result;
		}

		private DimensionType LoadDimensionType(string strFamilyName, string strTypeName)
		{
			string strFamilyFilePath = Product.FamilyLocation + "\\" + RevitVersion.Version + "\\OneKeyDim\\标高、坡道族、尺寸标注.rvt";
			return FindFamilySymbol.GetDimensionTypes(this.Doc, strFamilyFilePath, strFamilyName, strTypeName);
		}

		private void ModifySpotDimType(ref SpotDimensionType dimType)
		{
            YJKRevitBase.XmlUtility.XmlHelper xmlHelper = new YJKRevitBase.XmlUtility.XmlHelper(Product.DataLocation + string.Format("\\{0}.xml", "HY-高程点标注"), "Grid");
			string name = "Name";
			string name2 = "Value";
			foreach (XmlElement xmlElement in xmlHelper.GetElements())
			{
				IList<Parameter> parameters = dimType.GetParameters(xmlElement.GetAttribute(name));
				if (parameters.Count != 0)
				{
					Parameter parameter = parameters.First<Parameter>();
					if (parameter != null && !parameter.IsReadOnly)
					{
						if ("符号" == xmlElement.GetAttribute(name))
						{
							IList<Element> list = new FilteredElementCollector(this.Doc).OfCategory(BuiltInCategory.OST_SpotElevSymbols).ToElements();
							if (0 >= list.Count)
							{
								break;
							}
							string attribute = xmlElement.GetAttribute(name2);
							FamilySymbol familySymbol = null;
							foreach (Element element in list)
							{
								if (attribute == (element as FamilySymbol).Family.Name)
								{
									familySymbol = (element as FamilySymbol);
									break;
								}
							}
							if (familySymbol == null)
							{
								familySymbol = (list[0] as FamilySymbol);
							}
							parameter.Set(familySymbol.Id);
						}
						else if ("引线箭头" == xmlElement.GetAttribute(name))
						{
							parameter.Set(ElementId.InvalidElementId);
						}
						else if ("宽度系数" == xmlElement.GetAttribute(name))
						{
							parameter.SetValueString(xmlElement.GetAttribute(name2));
						}
						else
						{
                            switch ((int)parameter.StorageType)
							{
							case 1:
								parameter.Set(Convert.ToInt32(xmlElement.GetAttribute(name2)));
								break;
							case 2:
								parameter.Set(UnitUtility.MMToFeet(Convert.ToDouble(xmlElement.GetAttribute(name2))));
								break;
							case 3:
								parameter.Set(xmlElement.GetAttribute(name2));
								break;
							default:
								parameter.SetValueString(xmlElement.GetAttribute(name2));
								break;
							}
						}
					}
				}
			}
		}

		private List<IPlanarGeo> SpotGroupByLevel()
		{
			List<IPlanarGeo> list = new List<IPlanarGeo>();
			if (this.ArrayWindDoorInOutWallDataVisable.Count != 0)
			{
				List<IPlanarGeo> lstWinDoorGeo = new List<IPlanarGeo>();
				EnumerableExternsion.ForEach<IPlanarGeo>(this.ArrayWindDoorInOutWallDataVisable, delegate(IPlanarGeo v)
				{
					lstWinDoorGeo.Add(v);
				});
				List<List<IPlanarGeo>> list2 = new List<List<IPlanarGeo>>();
				for (int i = 0; i < lstWinDoorGeo.Count; i++)
				{
					IPlanarGeo planarGeo = lstWinDoorGeo[i];
					List<IPlanarGeo> list3 = new List<IPlanarGeo>();
					list3.Add(planarGeo);
					double topElev = planarGeo.TopElev;
					double bottomElev = planarGeo.BottomElev;
					for (int j = i + 1; j < lstWinDoorGeo.Count; j++)
					{
						IPlanarGeo planarGeo2 = lstWinDoorGeo[j];
						if (MathUtility.IsEqual(topElev - planarGeo2.TopElev, 0.0) && MathUtility.IsEqual(bottomElev - planarGeo2.BottomElev, 0.0))
						{
							list3.Add(planarGeo2);
							lstWinDoorGeo.RemoveAt(j);
							j--;
						}
					}
					list2.Add(list3);
				}
				if (list2.Count == 0)
				{
					return list;
				}
				foreach (List<IPlanarGeo> list4 in list2)
				{
					list4.Sort(new GeoComparerWithSpotRule(true));
					IPlanarGeo planarGeo3 = list4[0];
					List<IPlanarGeo> list5 = new List<IPlanarGeo>();
					list5.Add(planarGeo3);
					for (int k = 1; k < list4.Count; k++)
					{
						if (planarGeo3.Weight == list4[k].Weight)
						{
							list5.Add(list4[k]);
						}
					}
					list5.Sort(new GeoComparerWithSpotRule(false));
					planarGeo3 = list5[0];
					List<IPlanarGeo> list6 = new List<IPlanarGeo>();
					list6.Add(planarGeo3);
					for (int l = 1; l < list5.Count; l++)
					{
						if (planarGeo3.Width == list5[l].Width)
						{
							list6.Add(list5[l]);
						}
					}
					list6.Sort(new GeoComparerAtEqualLevel(true));
					list.Add(list6[0]);
				}
			}
			if (this.ArrayTopMostGeo.Count != 0)
			{
				this.AddTopGeoWithSpotDimRef(ref list);
			}
			return list;
		}

		private void DeleteExistedDimension()
		{
			Transaction transaction = new Transaction(this.Doc);
			try
			{
				transaction.Start("delete dimension list");
				ICollection<ElementId> verticalDimElementByDocView = Utility.GetVerticalDimElementByDocView(this.Doc);
				if (verticalDimElementByDocView.Count != 0)
				{
					this.Doc.Delete(Utility.GetVerticalDimElementByDocView(this.Doc));
				}
				transaction.Commit();
			}
			catch (Exception ex)
			{
				if (1 == (int)transaction.GetStatus())
				{
					transaction.RollBack();
				}
				throw ex;
			}
		}

		private void GetLevelPosition(ref XYZ ptLeft, ref XYZ ptRight)
		{
			try
			{
				XYZ xyz = this.TransformWcs2Plane.OfPoint(this.MinRegionPoint);
				if (MathUtility.LessThan(this.TransformWcs2Plane.OfPoint(this.MaxRegionPoint).X, xyz.X))
				{
					ptLeft = this.MaxRegionPoint;
					ptRight = this.MinRegionPoint;
				}
				else
				{
					ptLeft = this.MinRegionPoint;
					ptRight = this.MaxRegionPoint;
				}
				ptLeft -= this.Doc.ActiveView.RightDirection * Common.MMToFeet(4000.0);
				ptRight += this.Doc.ActiveView.RightDirection * Common.MMToFeet(4000.0);
			}
			catch (Exception ex)
			{
				throw ex;
			}
		}

		private void AddTopGeoWithSpotDimRef(ref List<IPlanarGeo> lstSpotDimRef)
		{
			try
			{
				if (this.ArrayTopMostGeo.Count != 0)
				{
					List<IPlanarGeo> topWallGeo = this.GetTopWallGeo(true);
					topWallGeo.AddRange(this.GetTopWallGeo(false));
					topWallGeo.Sort(new GeoComparerAtEqualLevel(true));
					this.RemoveSameTopElevationWallGeos(ref topWallGeo);
					lstSpotDimRef.AddRange(topWallGeo);
				}
			}
			catch
			{
			}
		}

		private List<IPlanarGeo> GetTopWallGeo(bool bByLeft = true)
		{
			List<IPlanarGeo> list = new List<IPlanarGeo>();
			try
			{
				XYZ xyz = this.TransformWcs2Plane.OfPoint((this.MaxRegionPoint + this.MinRegionPoint) / 2.0);
				foreach (IPlanarGeo planarGeo in this.ArrayTopMostGeo)
				{
					if (planarGeo.Weight == 8)
					{
						if (bByLeft)
						{
							if (!MathUtility.LessThan(planarGeo.Min2DPointECS.X, xyz.X, 1E-06))
							{
								continue;
							}
						}
						else if (!MathUtility.GreaterThan(planarGeo.Max2DPointECS.X, xyz.X, 1E-06))
						{
							continue;
						}
						if (!list.Contains(planarGeo))
						{
							list.Add(planarGeo);
						}
					}
				}
				if (list.Count == 0)
				{
					foreach (IPlanarGeo planarGeo2 in this.ArrayTopMostGeo)
					{
						if (bByLeft)
						{
							if (MathUtility.LessThan(planarGeo2.Min2DPointECS.X, xyz.X, 1E-06))
							{
								list.Add(planarGeo2);
								break;
							}
						}
						else if (MathUtility.GreaterThan(planarGeo2.Max2DPointECS.X, xyz.X, 1E-06))
						{
							list.Add(planarGeo2);
							break;
						}
					}
				}
				return list;
			}
			catch
			{
			}
			return list;
		}

		private bool IsExistSameGeo(List<IPlanarGeo> lstSpotDimRef, IPlanarGeo geoWall)
		{
			try
			{
				foreach (IPlanarGeo planarGeo in lstSpotDimRef)
				{
					if (geoWall.Element.Id.IntegerValue == planarGeo.Element.Id.IntegerValue)
					{
						return true;
					}
				}
			}
			catch
			{
			}
			return false;
		}

		private void RemoveSameTopElevationWallGeos(ref List<IPlanarGeo> lstTopWallGeos)
		{
			try
			{
				for (int i = lstTopWallGeos.Count - 1; i >= 0; i--)
				{
					for (int j = 0; j < i; j++)
					{
						if (MathUtility.IsEqual(lstTopWallGeos[i].TopElev, lstTopWallGeos[j].TopElev))
						{
							lstTopWallGeos.RemoveAt(i);
							i--;
							j--;
						}
					}
				}
			}
			catch
			{
			}
		}

		private void TestDimArrayBoundaryCv()
		{
			IList<Curve> list = this.CreateCurveBoxInViewPlane(this.MinRegionPoint, this.MaxRegionPoint);
			if (list == null)
			{
				return;
			}
			Transaction transaction = new Transaction(this.Doc, "Boundary");
			try
			{
				transaction.Start();
				CurveArray ArrayBoundaryCv = new CurveArray();
				EnumerableExternsion.ForEach<Curve>(list, delegate(Curve c)
				{
					ArrayBoundaryCv.Append(c);
				});
				this.Doc.Create.NewDetailCurveArray(this.Doc.ActiveView, ArrayBoundaryCv);
				transaction.Commit();
			}
			catch
			{
				transaction.RollBack();
			}
		}

		private void TestDimArrayElementShow()
		{
			List<ElementId> elementIds = (from e in this.ArrayPlanarGeo
			select e.Element.Id).ToList<ElementId>();
			this.UIApplication.ActiveUIDocument.Selection.SetElementIds(elementIds);
		}

		private readonly Document Doc;

		private readonly Plane Plane;

		private readonly Transform TransformWcs2Plane;

		private readonly IList<ViewPlan> ArrayViewPlan;

		private readonly UIApplication UIApplication;

		private OutWallSortAlgorithm OutWallSortAlgorithm;

		private GeoGroupManager GeoGroupManager;

		private readonly IDualStatusProgressBarProcess DualStatusProgressBarProcess;

		private Stopwatch Stopwatch;
	}
}
